#include <stdio.h>

#define MAX_STUDENTS 100    // 最大学生数
#define MAX_NAME_LENGTH 50  // 姓名最大字符长度

// 结构体定义
typedef struct 
{
    int id;
    char name[MAX_NAME_LENGTH];
    float scores[3];  // 三门课程成绩
    float total;
    float average;
} Student;

typedef struct 
{
    Student students[MAX_STUDENTS];
    int count;
} StudentManager;

// 初始化
void initManager(StudentManager *manager)
{
    manager->count = 0;
}

// 添加学生信息
void addStudent(StudentManager *manager)
{
    //判断学生人数是否已满
    if(manager->count > 100)
    {
        printf("学生信息存储已满！\n");
        return;
    }

    printf("添加第%d个学生信息\n",manager->count + 1);

    //输入学号
    while(1)
    {
        int is_flag = 0;
        printf("请输入学号：\n");

        //判断学号是否输入有误
        int input = scanf("%d",&manager->students[manager->count].id);
        if(input != 1)
        {
            while(getchar() != '\n');//清空输入缓冲区
            printf("输入有误，请输入正确格式的学号！\n");
            continue;
        }
        //判断学号是否重复
        for(int i = 0; i < manager->count; i++)
        {
            if(manager->students[manager->count].id == manager->students[i].id)
            {
                is_flag = 1;
                break;
            }
        }

        if(is_flag)
            printf("学号重复，请重新输入！\n");
        else   
            break;
    }

    //输入姓名
    printf("请输入姓名：\n");
    scanf("%s",manager->students[manager->count].name);

    //输入三科成绩
    printf("请输入三科的成绩：\n");
    scanf("%f %f %f",&manager->students[manager->count].scores[0],&manager->students[manager->count].scores[1],&manager->students[manager->count].scores[2]);

    //计算总分
    manager->students[manager->count].total = manager->students[manager->count].scores[0] + manager->students[manager->count].scores[1] + manager->students[manager->count].scores[2];
    printf("总分：%.1f\n",manager->students[manager->count].total);

    //计算平均值
    manager->students[manager->count].average = manager->students[manager->count].total / 3;
    printf("三门课程平均成绩：%.1f\n",manager->students[manager->count].average);

    manager->count++;   //学生数量增加
}

// 删除学生信息
void deleteStudent(StudentManager *manager)
{
    //判断是否有学生信息
    if(manager->count == 0)
    {
        printf("系统中无学生信息，无法操作！\n");
        return;
    }

    int n;
    printf("请输入要删除学生的学号：\n");
    scanf("%d",&n);

    int is_flag = 0;    //定义变量用来标记要删除学生在数组的位置
    for(int i = 0; i < manager->count; i++)
    {
        //找到要删除学生在数组中的下标
        if(n == manager->students[i].id)
        {
            is_flag = i+1;
            break;
        }
    }

    //根据标志位判断
    if(!is_flag)
    {
        printf("没有找到学号为%d的学生！\n",n);
        return;
    }

    for(int i = is_flag - 1; i < manager->count - 1; i++)
        manager->students[i] = manager->students[i+1];  //把要删除的学生后面的全部前移，覆盖要删除的学生的信息
    
    printf("已删除该学生信息！\n");
    manager->count--;   //学生总数量-1

}

// 修改学生信息
void modifyStudent(StudentManager *manager)
{
    //判断是否有学生信息
    if(manager->count == 0)
    {
        printf("系统中无学生信息，无法操作！\n");
        return;
    }

    int choice,n,is_exist = 0;
    printf("请输入要进行修改的学生的学号：\n");
    scanf("%d",&n);

    printf("请输入要进行的操作：1.修改学号 2.修改姓名 3.修改成绩 4.修改全部\n");
    scanf("%d",&choice);

    for(int i = 0; i < manager->count; i++)
    {
        //找到要修改学生在数组中的下标
        if(n == manager->students[i].id)
        {
            is_exist = i; 
            break;
        }
    }

    Student *p= &manager->students[is_exist];

    if(choice == 1 || choice == 4)
    {
        int newid;
        while(1)
        {   
            int is_flag = 0;
            printf("请输入修改后的学号：");
            if(scanf("%d",&newid) != 1)
            {
                printf("输入错误！\n");
                while(getchar() != '\n');
                continue;
            }
            
            for(int i = 0; i < manager->count; i++)
            {
                if(newid == manager->students[i].id)
                {
                    printf("该学号已存在,请重新输入！\n");
                    p->id = 0;
                    is_flag = 1;
                    break;
                }
            }

            if(is_flag == 0)
            {
                p->id = newid;
                break;
            }
        }
    }

    if(choice == 2 || choice == 4)
    {
        printf("请重新输入新的姓名：\n");
        scanf("%s",p->name);
    }

    if(choice == 3 || choice == 4)
    {
        printf("请重新输入新的成绩：\n");
        printf("成绩1：\n");
        scanf("%f",&p->scores[0]);
        printf("成绩2：\n");
        scanf("%f",&p->scores[1]);
        printf("成绩3：\n");
        scanf("%f",&p->scores[2]);

        p->total = p->scores[0] + p->scores[1] + p->scores[2];
        p->average = p->total / 3;
    }
}

// 查询学生
void queryStudent(StudentManager *manager)
{
    //判断是否有学生信息
    if(manager->count == 0)
    {
        printf("系统中无学生信息，无法操作！\n");
        return;
    }
    int n;
    printf("请输入要进行查询的学生的学号：\n");
    scanf("%d",&n);

    for(int i = 0; i < manager->count; i++)
    {
        if(n == manager->students[i].id)
        {
            printf("学号\t姓名\t成绩1\t成绩2\t成绩3\t总分\t平均分\n");
            printf("%d\t%s\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",
            manager->students[i].id,manager->students[i].name,manager->students[i].scores[0],
            manager->students[i].scores[1],manager->students[i].scores[2],manager->students[i].total,
            manager->students[i].average);
            break;
        }
    }
}

// 排序学生(按总分降序)
void sortStudents(StudentManager *manager)
{
    //判断是否有学生信息
    if(manager->count == 0)
    {
        printf("系统中无学生信息，无法操作！\n");
        return;
    }
    
    for(int i = 0; i < manager->count-1; i++)
    {
        for(int j = 0; j < manager->count - i - 1; j++)
        {
            if(manager->students[j].total < manager->students[j+1].total)
            {
                Student p = manager->students[j];
                manager->students[j] = manager->students[j+1];
                manager->students[j+1] = p;
            }
        }
    }
}

// 显示所有学生信息
void displayAll(StudentManager *manager)
{
    //判断是否有学生信息
    if(manager->count == 0)
    {
        printf("系统中无学生信息，无法操作！\n");
        return;
    }

    printf("所有学生信息如下：\n");

    printf("学号\t姓名\t成绩1\t成绩2\t成绩3\t总分\t平均分\n");
    for(int i = 0; i < manager->count; i++)
    {
        //格式化输出
        printf("%d\t%s\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",
            manager->students[i].id,manager->students[i].name,manager->students[i].scores[0],
            manager->students[i].scores[1],manager->students[i].scores[2],manager->students[i].total,
            manager->students[i].average);
    }
}


// 文件保存
void saveToFile(StudentManager *manager)
{
    FILE *fp = fopen("students.txt","w");
    if(fp == NULL)
    {
        printf("文件打开失败，保存失败！\n");
        return;
    }

    fprintf(fp,"学生总数量：%d\n",manager->count);

    //写入学生信息
    for(int i = 0; i < manager->count; i++)
    {
        Student *s = &manager->students[i];
        fprintf(fp,"id：%d ",s->id);
        fprintf(fp,"name：%s ",s->name);
        fprintf(fp,"score1：%.1f ",s->scores[0]);
        fprintf(fp,"score2：%.1f ",s->scores[1]);
        fprintf(fp,"score3：%.1f ",s->scores[2]);
        fprintf(fp,"total：%.1f ",s->total);
        fprintf(fp,"average：%.1f\n",s->average);
        
    }
    fclose(fp);
    printf("文件已保存！\n");
}

// 文件加载
void loadFromFile(StudentManager *manager) {
    // 以读写模式打开文件
    FILE *fp = fopen("students.txt", "r+");
    if (fp == NULL) {
        printf("文件不存在或打开失败，加载失败！\n");
        return;
    }

    // 读取学生数量
    int loadCount;
    fscanf(fp, "学生总数量：%d\n", &loadCount);
    if (loadCount > MAX_STUDENTS) {
        printf("⚠️ 文件数据过多，仅加载前%d名学生！\n", MAX_STUDENTS);
        loadCount = MAX_STUDENTS;
    }

    // 清空现有数据
    manager->count = 0;
    // 读取每个学生信息
    for (int i = 0; i < loadCount; i++) {
        Student *s = &manager->students[i];
        fscanf(fp, "id：%d ", &s->id);
        fscanf(fp, "name：%s ", s->name);
        fscanf(fp, "score1：%f ", &s->scores[0]);
        fscanf(fp, "score2：%f ", &s->scores[1]);
        fscanf(fp, "score3：%f ", &s->scores[2]);
        fscanf(fp, "total：%f ",&s->total);
        fscanf(fp, "average：%f\n",&s->average);
        manager->count++;
    }

    fclose(fp);
    printf("已从 students.txt 加载数据，共%d名学生！\n", manager->count);
}

int main(int argc, char const *argv[])
{
    StudentManager *manager;
    initManager(manager);   //初始化
    loadFromFile(manager);

    int choice;
    while(1)
    {
        printf("==========================\n");
        printf("     学生成绩管理系统      \n");
        printf("==========================\n");

        printf("请输入选择的数字：\n");
        printf("1.添加学生    2.删除学生     3.修改学生  4.查询学生\n");
        printf("5.按总分降序  6.显示所有学生  7.保存数据  8.加载数据 0.退出系统\n");

        scanf("%d",&choice);

        switch (choice)
        {
        case 1:
            addStudent(manager);
            break;
        case 2:
            deleteStudent(manager);
            break;
        case 3:
            modifyStudent(manager);
            break;
        case 4:
            queryStudent(manager);
            break;
        case 5:
            sortStudents(manager);
            break;
        case 6:
            displayAll(manager);
            break;
        case 7:
            saveToFile(manager);
            break;
        case 8:
            loadFromFile(manager);
            break;
        case 0:
            printf("退出成功！\n");
            return 0;
        default:
            printf("无效选项，请重新输入！\n");
        }
    }
}

